﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using BattleMaster_IRCbot.UserCommands;
using Meebey.SmartIrc4net;

namespace BattleMaster_IRCbot
{
    class Game
    {
        private List<Character> _characters = new List<Character>();
        private List<Command> _commands = new List<Command>();
        public IRChandler ircHandler;
        static string activeDirectory = Directory.GetCurrentDirectory();
        public List<Character> Characters { get { return _characters; } }
        public List<Command> Commands { get { return _commands; } }

        public Game()
        {
            Initialize();
        }

        private void Initialize()
        {
            System.Console.WriteLine("Initializing... ");

            // Check to make sure all game directories exist. If they do not, create them.
            if (!Directory.Exists(activeDirectory + @"\Players"))
            {
                Directory.CreateDirectory(activeDirectory + @"\Players");
                System.Console.WriteLine("Directory \"Players\" created.");
            }

            if (!Directory.Exists(activeDirectory + @"\Items"))
            {
                Directory.CreateDirectory(activeDirectory + @"\Items");
                System.Console.WriteLine("Directory \"Items\" created.");
            }

            // Add command instances to the command list

            Commands.Add(new Help());
            Commands.Add(new Login());
            Commands.Add(new Logout());
            Commands.Add(new MakeCharacter());
            Commands.Add(new Quit());
            Commands.Add(new Status());

            System.Console.WriteLine("Initialization Done.");
        }

        public void addCharacter(string usrNick)
        {
            try { Characters.Add(new Character(usrNick)); }
            catch (DirectoryNotFoundException ex) { throw ex; }
            catch (FileNotFoundException ex) { throw ex; }
        }

        public void CreateCharacter(string usrNick)
        {
            //Check to see if character already exists
            string filePath = activeDirectory + @"\Players\" + usrNick + ".xml";
            if (!File.Exists(filePath))
            {
                this.makeUserFile(usrNick);
            }

            XmlDocument doc = new XmlDocument();
            doc.Load(filePath);
        }

        public bool isLoggedIn(string playerNick)
        {
            bool loggedIn = false;
            foreach (Character C in this._characters)
            {
                if (C.Name == playerNick) loggedIn = true;
            }
            return loggedIn;
        }

        //Temporary method to provide the character template
        static string[] makeTemplate()
        {
            //Create and return an array of basic character data.
            string[] template = new string[10];
            template[0] = "--Account";
            template[1] = "Password:null";
            template[2] = "--Character";
            template[3] = "HP:100/100";
            template[4] = "MP:100/100";
            template[5] = "Strength:10";
            template[6] = "Defence:10";
            template[7] = "Speed:10";
            template[8] = "Agility:10";
            template[9] = "--Inventory";
            return template;
        }

        public void makeUserFile(string userNick)
        {
            try
            {
                string filePath = activeDirectory + @"\Players\" + userNick + ".xml";
                if (!File.Exists(filePath))
                {
                    Console.WriteLine(String.Format("Creating user file for {0}.", userNick));
                    XmlTextWriter textWriter = new XmlTextWriter(filePath, null);
                    textWriter.WriteStartDocument();
                    textWriter.WriteStartElement("Player");
                    textWriter.WriteStartElement("Accuont");
                    textWriter.WriteStartElement("Password");
                    textWriter.WriteEndElement(); // Close Password Element
                    textWriter.WriteEndElement(); // Close Account Element
                    textWriter.WriteStartElement("Character");
                    textWriter.WriteEndElement();  // Close Character Element
                    textWriter.WriteStartElement("Inventory");
                    textWriter.WriteEndElement(); // Close Inventory Element
                    textWriter.WriteEndElement(); // Close Player Element
                    textWriter.WriteEndDocument();
                    textWriter.Close();
                }
            }
            catch (Exception e) { System.Console.WriteLine(e.Message); }
        }

        public string ProcessInput(string msgOrigen, string msgContent)
        {
            string output = "";
            string cmdBuffer = msgContent.Trim();
            while (msgContent.Contains("  "))
            {
                cmdBuffer = cmdBuffer.Replace("  ", " ");
            }
            string[] cmd = cmdBuffer.Split(' ');
            try
            {
                bool commandFound = false;
                foreach (Command C in _commands)
                {
                    // Check to see if input maches the name of a command
                    if (C.Name.ToLower() == cmd[0].ToLower())
                    {
                        commandFound = true;
                        C.Verb(this, msgOrigen, cmd);
                        break;
                    }
                    else
                    {
                        // Check to see if input maches one of the command's aliasses
                        for (int i = 0; i < C.Aliasses.Length; i++)
                        {
                            if (C.Aliasses[i].ToLower() == cmd[0].ToLower())
                            {
                                commandFound = true;
                                C.Verb(this, msgOrigen, cmd);
                                break;
                            }
                        }
                    }
                }
                if (!commandFound && this.isLoggedIn(msgOrigen)) // Check the character command list if available.
                {
                    Character playerCharacter = null;

                    // Get a refrence to the character object
                    foreach (Character C in this._characters)
                    {
                        if (C.Name == msgOrigen) playerCharacter = C;
                    }

                    foreach (Command C in playerCharacter.Commands)
                    {
                        // Check to see if input maches the name of a command
                        if (C.Name.ToLower() == cmd[0].ToLower())
                        {
                            commandFound = true;
                            C.Verb(this, msgOrigen, cmd);
                            break;
                        }
                        else
                        {
                            // Check to see if input maches one of the command's aliasses
                            for (int i = 0; i < C.Aliasses.Length; i++)
                            {
                                if (C.Aliasses[i].ToLower() == cmd[0].ToLower())
                                {
                                    commandFound = true;
                                    C.Verb(this, msgOrigen, cmd);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            catch (IndexOutOfRangeException ex) { output = "--Bad Arguments--"; }

            return output;
        }

        public void removeCharacter(string characterName)
        {
            foreach (Character C in _characters)
            {
                if (C.Name == characterName)
                {
                    try
                    {
                        Characters.Remove(C);
                        break;
                    }
                    catch (Exception ex) { throw new Exception("Character not found in active list. Are you logged in?"); }
                }
            }
        }
    }
}
